﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
using CAION2.Classes;
using CAION2.Commands;
using CAION2.Models;
using CAION2.Properties;
using CAION2.Views;
using FirstFloor.ModernUI.Windows.Controls;
using CAION2.Helpers;

namespace CAION2.ViewModels
{
    using FirstFloor.ModernUI.Presentation;
    using RelayCommand = RelayCommand;

    public class ItemCardViewModel : ViewModelBase
    {
        public class StatsValuesClass
        {
            public string Stat;

            public string Translate;

            public string Unit;

            public Single BasicValue;

            public Single BasicValue2;

            public Single BonusValue;

            public Single EnchantValue;

            public Single ManaStoneValue;

            public Single RandomBonusValue;

            public Single IdianValue;

            public Single GodEnchantValue;

            public Single ArmsfusionBonusValue;

            public Single ArmsfusionManaStoneValue;

            public String Tips;


            public StatsValuesClass()
            {
                
            }

            public StatsValuesClass(char valueId, string stat, Single value, Single value2 = 0, string unit = "")
            {
                Stat = stat;
                Translate = CardStat.GetStatTranslate(Stat);
                Unit = unit;

                switch (valueId)
                {
                    case 'e':
                        EnchantValue = value;
                        break;
                    case 'm':
                        ManaStoneValue = value;
                        break;
                    case 'b':
                        BonusValue = value;
                        break;
                    case 'r':
                        RandomBonusValue = value;
                        break;
                    case 'i':
                        IdianValue = value;
                        break;
                    case 'g':
                        GodEnchantValue = value;
                        break;
                    case 'a':
                        ArmsfusionBonusValue = value;
                        break;
                    case 'n':
                        ArmsfusionManaStoneValue = value;
                        break;
                    case 'x':
                        BasicValue = value;
                        BasicValue2 = value2;
                        break;
                }
            }

            public void UpdateStatValue(
                char valueId,
                Single value,
                Single value2 = 0,
                EnchantStates state = EnchantStates.Value,
                string unit = "")
            {
                if (!string.IsNullOrEmpty(unit)) Unit = unit;

                switch (state)
                {
                    case EnchantStates.Value:
                        switch (valueId)
                        {
                            case 'e':
                                EnchantValue = value;
                                break;
                            case 'm':
                                ManaStoneValue = value;
                                break;
                            case 'b':
                                BonusValue = value;
                                break;
                            case 'r':
                                RandomBonusValue = value;
                                break;
                            case 'i':
                                IdianValue = value;
                                break;
                            case 'g':
                                GodEnchantValue = value;
                                break;
                            case 'a':
                                ArmsfusionBonusValue = value;
                                break;
                            case 'n':
                                ArmsfusionManaStoneValue = value;
                                break;
                            case 'x':
                                BasicValue = value;
                                BasicValue2 = value2;
                                break;
                        }
                        break;
                    case EnchantStates.Plus:
                        switch (valueId)
                        {
                            case 'e':
                                EnchantValue += value;
                                break;
                            case 'm':
                                ManaStoneValue += value;
                                break;
                            case 'b':
                                BonusValue += value;
                                break;
                            case 'r':
                                RandomBonusValue += value;
                                break;
                            case 'i':
                                IdianValue += value;
                                break;
                            case 'g':
                                GodEnchantValue += value;
                                break;
                            case 'a':
                                ArmsfusionBonusValue += value;
                                break;
                            case 'n':
                                ArmsfusionManaStoneValue += value;
                                break;
                            case 'x':
                                BasicValue += value;
                                BasicValue2 += value2;
                                break;
                        }
                        break;
                    case EnchantStates.Minus:
                        switch (valueId)
                        {
                            case 'e':
                                EnchantValue -= value;
                                break;
                            case 'm':
                                ManaStoneValue -= value;
                                break;
                            case 'b':
                                BonusValue -= value;
                                break;
                            case 'r':
                                RandomBonusValue -= value;
                                break;
                            case 'i':
                                IdianValue -= value;
                                break;
                            case 'g':
                                GodEnchantValue -= value;
                                break;
                            case 'a':
                                ArmsfusionBonusValue -= value;
                                break;
                            case 'n':
                                ArmsfusionManaStoneValue -= value;
                                break;
                            case 'x':
                                BasicValue -= value;
                                BasicValue2 -= value2;
                                break;
                        }
                        break;
                }
            }

            public Single Sum()
            {
                return EnchantValue 
                    + ManaStoneValue 
                    + BonusValue 
                    + RandomBonusValue 
                    + IdianValue 
                    + GodEnchantValue
                    + ArmsfusionBonusValue
                    + ArmsfusionManaStoneValue;
            }

            public string BasicValueText()
            {
                if (Math.Abs(BasicValue) <= 0) return "";
                if (BasicValue2 > 0) return BasicValue + " - " + BasicValue2;
                return BasicValue.ToString(CultureInfo.InvariantCulture);
            }

            public string SumValueText()
            {
                Single sum = Sum();
                if (Math.Abs(sum) <= 0) return "";

                string sign = "+";
                if (sum < 0) sign = "";

                if (BasicValue > 0)
                {
                    return "[color=" + AppearanceManager.Current.AccentColor + "] " + sign + sum + Unit + "[/color]";
                }
                return "[color=" + AppearanceManager.Current.AccentColor + "]" + sign + sum + Unit + "[/color]";
            }

            public StatsValuesClass Clone()
            {
                return new StatsValuesClass
                                          {
                                              Stat = Stat,
                                              Translate = Translate,
                                              Unit = Unit,
                                              BasicValue = BasicValue,
                                              BasicValue2 = BasicValue2,
                                              BonusValue = BonusValue,
                                              EnchantValue = EnchantValue,
                                              ManaStoneValue = ManaStoneValue,
                                              RandomBonusValue = RandomBonusValue,
                                              IdianValue = IdianValue,
                                              GodEnchantValue = GodEnchantValue,
                                              ArmsfusionBonusValue = ArmsfusionBonusValue,
                                              ArmsfusionManaStoneValue =
                                                  ArmsfusionManaStoneValue,
                                              Tips = Tips
                                          };
            }
        }

        public enum EnchantStates
        {
            Value,

            Plus,

            Minus
        }

        

        #region Vars & Properties

            #region General
        
        private List<StatsValuesClass> statsList;
        private bool firstPageChecked;

        private String fullCharacters;
        private String fullCharacters2;
        private String mainCharacters;

        private ObservableCollection<Visibility> pagesVisible;
        private byte placeIndex;
        private bool isCraftItem;

        private string translateName;
        private SolidColorBrush translateColor;

        private static readonly List<string> JewelMarks = new List<string>
                                                          {
                                                              "right_or_left_ear",
                                                              "neck",
                                                              "right_or_left_finger",
                                                              "waist"
                                                          };

        public Visibility CardVisible
        {
            get
            {
                return _cardVisible;
            }
            set
            {
                if (Equals(_cardVisible, value)) return;

                _cardVisible = value;
                OnPropertyChanged("CardVisible");
            }
        }

        public ObservableCollection<Visibility> PagesVisible
        {
            get
            {
                return pagesVisible;
            }
            private set
            {
                if (Equals(pagesVisible, value)) return;

                pagesVisible = value;
                OnPropertyChanged("PagesVisible");
            }
        }

        public bool FirstPageChecked
        {
            get
            {
                return firstPageChecked;
            }
            set
            {
                firstPageChecked = value;
                OnPropertyChanged("FirstPageChecked");
            }
        }

        public bool CardIsLoaded { get; private set; }

        public byte PlaceIndex
        {
            private get
            {
                return placeIndex;
            }
            set
            {
                if (Equals(placeIndex, value)) return;

                placeIndex = value;

                if (PlaceIndex > 0) IsSendStats = true;
            }
        }

        private bool IsSendStats { get; set; }

        private List<StatsValuesClass> StatsList
        {
            get
            {
                return statsList;
            }
            set
            {
                if (Equals(statsList, value)) return;

                statsList = value;
                OnPropertyChanged("StatsList");
            }
        }

        public String FullCharacters
        {
            get
            {
                return fullCharacters;
            }
            private set
            {
                if (Equals(fullCharacters, value)) return;

                fullCharacters = value;
                OnPropertyChanged("FullCharacters");
            }
        }

        public String FullCharacters2
        {
            get
            {
                return fullCharacters2;
            }
            private set
            {
                if (Equals(fullCharacters2, value)) return;

                fullCharacters2 = value;
                OnPropertyChanged("FullCharacters2");
            }
        }

        public String MainCharacters
        {
            get
            {
                return mainCharacters;
            }
            private set
            {
                if (Equals(mainCharacters, value)) return;

                mainCharacters = value;
                OnPropertyChanged("MainCharacters");
            }
        }

        public string TranslateName
        {
            get
            {
                return translateName;
            }

            private set
            {
                if (translateName == value) return;

                translateName = value;
                OnPropertyChanged("TranslateName");
            }
        }

        public BitmapImage Icon
        {
            get
            {
                return _icon;
            }

            private set
            {
                if (Equals(_icon, value)) return;

                _icon = value;
                OnPropertyChanged("Icon");
            }
        }

        public bool IsCraftItem
        {
            set
            {
                isCraftItem = value;
            }
        }

        public SolidColorBrush TranslateColor
        {
            get
            {
                return translateColor;
            }

            private set
            {
                if (Equals(translateColor, value)) return;

                translateColor = value;
                OnPropertyChanged("TranslateColor");
            }
        }

        public ObservableCollection<Visibility> ExchangeVisible
        {
            get
            {
                return _exchangeVisible;
            }
            private set
            {
                if (Equals(_exchangeVisible, value)) return;

                _exchangeVisible = value;
                OnPropertyChanged("ExchangeVisible");
            }
        }

        public string CardTag
        {
            get
            {
                return _cardTag;
            }
            private set
            {
                if (Equals(_cardTag, value)) return;

                _cardTag = value;
                OnPropertyChanged("CardTag");

                CardVisible = Visibility.Hidden;
            }
        }

            #endregion

            #region Items

        private DataRow _item;
        private DataRow _saveItem;
        private DataRow _saveItem2;
        
        private BitmapImage _icon;
        private string _itemType;
        private string _itemSpeed;
        private string _itemLevel;
        private string _itemLevelTag;
        private string _itemSoul;
        private string _itemExchange;
        private ObservableCollection<Visibility> _exchangeVisible;

        private Visibility _itemsSelectorVisible;
        private byte _loadItemIndex;
        private Visibility _cardVisible;
        private string _cardTag;

        private string _itemId;

        public byte LoadItemIndex
        {
            set
            {
                if (Equals(_loadItemIndex, value)) return;

                _loadItemIndex = value;
            }
        }

        public DataRow Item
        {
            get
            {
                return _item;
            }
            set
            {
                if (Equals(_item, value)) return;

                _item = value;
                OnPropertyChanged("Item");
            }
        }

        public DataRow SaveItem
        {
            get
            {
                return _saveItem;
            }
            set
            {
                if (Equals(_saveItem, value)) return;
                _saveItem = value;
            }
        }

        public DataRow SaveItem2
        {
            private get
            {
                return _saveItem2;
            }
            set
            {
                if (Equals(_saveItem2, value)) return;
                _saveItem2 = value;
            }
        }
        
        public Visibility ItemsSelectorVisible
        {
            get
            {
                return _itemsSelectorVisible;
            }
            private set
            {
                if (Equals(_itemsSelectorVisible, value)) return;

                _itemsSelectorVisible = value;
                OnPropertyChanged("ItemsSelectorVisible");
            }
        }
        
        public string ItemType
        {
            get
            {
                return _itemType;
            }
            private set
            {
                if (Equals(_itemType, value)) return;

                _itemType = value;
                OnPropertyChanged("ItemType");
            }
        }

        public string ItemSpeed
        {
            get
            {
                return _itemSpeed;
            }
            private set
            {
                if (Equals(_itemSpeed, value)) return;

                _itemSpeed = value;
                OnPropertyChanged("ItemSpeed");
            }
        }

        public string ItemLevel
        {
            get
            {
                return _itemLevel;
            }
            private set
            {
                if (Equals(_itemLevel, value)) return;

                _itemLevel = value;
                OnPropertyChanged("ItemLevel");
            }
        }

        public string ItemLevelTag
        {
            get
            {
                return _itemLevelTag;
            }
            private set
            {
                if (Equals(_itemLevelTag, value)) return;

                _itemLevelTag = value;
                OnPropertyChanged("ItemLevelTag");
            }
        }

        public string ItemSoul
        {
            get
            {
                return _itemSoul;
            }
            private set
            {
                if (Equals(_itemSoul, value)) return;

                _itemSoul = value;
                OnPropertyChanged("ItemSoul");
            }
        }

        public string ItemExchange
        {
            get
            {
                return _itemExchange;
            }
            private set
            {
                if (Equals(_itemExchange, value)) return;

                _itemExchange = value;
                OnPropertyChanged("ItemExchange");
            }
        }

        public string ItemId
        {
            get
            {
                return _itemId;
            }
            private set
            {
                if (Equals(_itemId, value)) return;

                _itemId = value;
                OnPropertyChanged("ItemId");
            }
        }

            #endregion

            #region Armsfusion

        private Visibility armsfusionVisible;
        private Visibility armsfusionBonusVisible;
        private Visibility armsfusionManastonesVisible;
        private string armsfusionBonusCharacters;
        private ObservableCollection<ManaStone> armsfusionManastones;
        private string armsfusionManastoneText;
        private byte armsfusionManastonesMaxLevel;
        private SolidColorBrush armsfusionTitleColor;

        private DataRow ArmsfusionItem { get; set; }

        public Visibility ArmsfusionVisible
        {
            get
            {
                return armsfusionVisible;
            }
            private set
            {
                if (Equals(armsfusionVisible, value)) return;

                armsfusionVisible = value;
                OnPropertyChanged("ArmsfusionVisible");
            }
        }

        public Visibility ArmsfusionBonusVisible
        {
            get
            {
                return armsfusionBonusVisible;
            }
            private set
            {
                if (Equals(armsfusionBonusVisible, value)) return;

                armsfusionBonusVisible = value;
                OnPropertyChanged("ArmsfusionBonusVisible");
            }
        }

        public Visibility ArmsfusionManastonesVisible
        {
            get
            {
                return armsfusionManastonesVisible;
            }
            private set
            {
                if (Equals(armsfusionManastonesVisible, value)) return;

                armsfusionManastonesVisible = value;
                OnPropertyChanged("ArmsfusionManastonesVisible");
            }
        }

        public string ArmsfusionBonusCharacters
        {
            get
            {
                return armsfusionBonusCharacters;
            }
            private set
            {
                if (Equals(armsfusionBonusCharacters, value)) return;

                armsfusionBonusCharacters = value;
                OnPropertyChanged("ArmsfusionBonusCharacters");
            }
        }

        public bool IsArmsfusionItem { get; set; }

        public ObservableCollection<ManaStone> ArmsfusionManastones
        {
            get
            {
                return armsfusionManastones;
            }
            private set
            {
                if (Equals(armsfusionManastones, value)) return;

                armsfusionManastones = value;
                OnPropertyChanged("ArmsfusionManastones");
            }
        }

        public string ArmsfusionManastoneText
        {
            get
            {
                return armsfusionManastoneText;
            }
            set
            {
                if (Equals(armsfusionManastoneText, value)) return;

                armsfusionManastoneText = value;
                OnPropertyChanged("ArmsfusionManastoneText");
            }
        }

        public SolidColorBrush ArmsfusionTitleColor
        {
            get
            {
                return armsfusionTitleColor;
            }

            private set
            {
                if (Equals(armsfusionTitleColor, value)) return;

                armsfusionTitleColor = value;
                OnPropertyChanged("ArmsfusionTitleColor");
            }
        }

        public List<KeyValuePair<string, float>> ArmsfusionGodEnchantStats { get; set; }

        #endregion

            #region Manastones

        private Visibility manastonesVisible;
        private ObservableCollection<ManaStone> manastones;
        private string manastoneText;

        public byte ManastonesMaxLevel { get; set; }
        public string ManastoneText
        {
            get
            {
                return manastoneText;
            }
            set
            {
                if (Equals(manastoneText, value)) return;

                manastoneText = value;
                OnPropertyChanged("ManastoneText");
            }
        }

        public Visibility ManastonesVisible
        {
            get
            {
                return manastonesVisible;
            }
            private set
            {
                if (Equals(manastonesVisible, value)) return;

                manastonesVisible = value;
                OnPropertyChanged("ManastonesVisible");
            }
        }

        public ObservableCollection<ManaStone> Manastones
        {
            get
            {
                return manastones;
            }
            private set
            {
                if (Equals(manastones, value)) return;

                manastones = value;
                OnPropertyChanged("Manastones");
            }
        }
        
            #endregion

            #region Bonuses

        private Visibility bonusVisible;
        private String bonusCharacters;

        public Visibility BonusVisible
        {
            get
            {
                return bonusVisible;
            }
            private set
            {
                if (Equals(bonusVisible, value)) return;

                bonusVisible = value;
                OnPropertyChanged("BonusVisible");
            }
        }

        public string BonusCharacters
        {
            get
            {
                return bonusCharacters;
            }
            private set
            {
                if (Equals(bonusCharacters, value)) return;

                bonusCharacters = value;
                OnPropertyChanged("BonusCharacters");
            }
        }

            #endregion

            #region Enchant

        private Visibility enchantVisible;
        private string enchantLevelText;
        private byte enchant;
        private byte maximumEnchant;

        public string EnchantLevelText
        {
            get
            {
                return enchantLevelText;
            }
            private set
            {
                if (Equals(enchantLevelText, value)) return;

                enchantLevelText = value;
                OnPropertyChanged("EnchantLevelText");
            }
        }

        public byte Enchant
        {
            get
            {
                return enchant;
            }
            set
            {
                EnchantLevelText = String.Format("{0}  {1}/{2}", Resources.Enchant, value, MaximumEnchant);

                if (Equals(enchant, value)) return;

                enchant = value;
                OnPropertyChanged("Enchant");

                GetEnchantStats();

                ShowFullStatsTable();
            }
        }

        public Visibility EnchantVisible
        {
            get
            {
                return enchantVisible;
            }
            private set
            {
                if (Equals(enchantVisible, value)) return;

                enchantVisible = value;
                OnPropertyChanged("EnchantVisible");
            }
        }

        public byte MaximumEnchant
        {
            get
            {
                return maximumEnchant;
            }
            private set
            {
                if (Equals(maximumEnchant, value)) return;

                maximumEnchant = value;
                OnPropertyChanged("MaximumEnchant");
            }
        }

            #endregion

            #region Idian

        private Visibility idianVisible;
        private Idian idian;
        private byte idianMaxLevel;
        private string idianText;
        private String idianCharacters;

        public string IdianText
        {
            get
            {
                return idianText;
            }
            set
            {
                if (Equals(idianText, value)) return;

                idianText = value;
                OnPropertyChanged("IdianText");
            }
        }

        private Idian Idian
        {
            get
            {
                return idian;
            }
            set
            {
                if (Equals(idian, value)) return;

                idian = value;
                OnPropertyChanged("Idian");

                CreateIdianTable();
            }
        }

        public Visibility IdianVisible
        {
            get
            {
                return idianVisible;
            }
            private set
            {
                if (Equals(idianVisible, value)) return;

                idianVisible = value;
                OnPropertyChanged("IdianVisible");
            }
        }

        public string IdianCharacters
        {
            get
            {
                return idianCharacters;
            }
            private set
            {
                if (Equals(idianCharacters, value)) return;

                idianCharacters = value;
                OnPropertyChanged("IdianCharacters");
            }
        }

            #endregion

            #region God Enchant

        private Visibility godEnchantVisible;
        private string godEnchantCharactersLevel1;
        private string godEnchantCharactersLevel2;
        private string godEnchantText;
        private byte godEnchantLevel;
        private byte godEnchantMaxLevel;
        private float[] godEnchantLevelsOpacity;

        public byte GodEnchantLevel
        {
            get
            {
                return godEnchantLevel;
            }
            set
            {
                GodEnchantText = string.Format(Resources.GodEnchant_Level, value);

                if (Equals(godEnchantLevel, value)) return;
                godEnchantLevel = value;

                OnPropertyChanged("GodEnchantLevel");

                SetGodEnchantCharactersOpacity();
                GetGodEnchantStats();
            }
        }

        public string GodEnchantText
        {
            get
            {
                return godEnchantText;
            }
            set
            {
                if (Equals(godEnchantText, value)) return;

                godEnchantText = value;
                OnPropertyChanged("GodEnchantText");
            }
        }

        public byte GodEnchantMaxLevel
        {
            get
            {
                return godEnchantMaxLevel;
            }
            private set
            {
                if (Equals(godEnchantMaxLevel, value)) return;
                godEnchantMaxLevel = value;

                OnPropertyChanged("GodEnchantMaxLevel");
            }
        }

        public Visibility GodEnchantVisible
        {
            get
            {
                return godEnchantVisible;
            }
            private set
            {
                if (Equals(godEnchantVisible, value)) return;

                godEnchantVisible = value;
                OnPropertyChanged("GodEnchantVisible");
            }
        }

        public string GodEnchantCharactersLevel1
        {
            get
            {
                return godEnchantCharactersLevel1;
            }
            set
            {
                if (Equals(godEnchantCharactersLevel1, value)) return;

                godEnchantCharactersLevel1 = value;
                OnPropertyChanged("godEnchantCharactersLevel1");
            }
        }

        public string GodEnchantCharactersLevel2
        {
            get
            {
                return godEnchantCharactersLevel2;
            }
            set
            {
                if (Equals(godEnchantCharactersLevel2, value)) return;

                godEnchantCharactersLevel2 = value;
                OnPropertyChanged("godEnchantCharactersLevel2");
            }
        }

        public float[] GodEnchantLevelsOpacity
        {
            get
            {
                return godEnchantLevelsOpacity;
            }
            set
            {
                if (Equals(value, godEnchantLevelsOpacity)) return;
                godEnchantLevelsOpacity = value;

                OnPropertyChanged("GodEnchantLevelsOpacity");
            }
        }

        public List<KeyValuePair<string, float>> GodEnchantStats { get; set; }

        #endregion

            #region ItemSet

        private Visibility itemSetVisible;
        private string itemSetText;
        private String itemSetCharacters;
        private ItemSet itemSet;

        public Visibility ItemSetVisible
        {
            get
            {
                return itemSetVisible;
            }
            private set
            {
                if (Equals(itemSetVisible, value)) return;

                itemSetVisible = value;
                OnPropertyChanged("ItemSetVisible");
            }
        }

        public string ItemSetText
        {
            get
            {
                return itemSetText;
            }
            set
            {
                if (Equals(itemSetText, value)) return;

                itemSetText = value;
                OnPropertyChanged("ItemSetText");
            }
        }

        public string ItemSetCharacters
        {
            get
            {
                return itemSetCharacters;
            }
            private set
            {
                if (Equals(itemSetCharacters, value)) return;

                itemSetCharacters = value;
                OnPropertyChanged("ItemSetCharacters");
            }
        }

        public ItemSet ItemSet
        {
            get
            {
                return itemSet;
            }
            set
            {
                if (Equals(itemSet, value)) return;

                itemSet = value;
            }
        }

            #endregion

            #region Coins

        private string extraCurrencyIcon;
        private string extraCurrencyName;
        private ObservableCollection<DataRow> coins;
        private List<Visibility> abyssPointsVisible;

        public ObservableCollection<DataRow> Coins
        {
            get
            {
                return coins;
            }
            private set
            {
                if (Equals(coins, value)) return;

                coins = value;
                OnPropertyChanged("Coins");
            }
        }

        public string ExtraCurrencyIcon
        {
            get
            {
                return extraCurrencyIcon;
            }
            set
            {
                if (Equals(extraCurrencyIcon, value)) return;
                extraCurrencyIcon = value;

                OnPropertyChanged("ExtraCurrencyIcon");
            }
        }

        public string ExtraCurrencyName
        {
            get
            {
                return extraCurrencyName;
            }
            set
            {
                if (Equals(extraCurrencyName, value)) return;
                extraCurrencyName = value;

                OnPropertyChanged("ExtraCurrencyName");
            }
        }

        public List<Visibility> AbyssPointsVisible
        {
            get
            {
                return abyssPointsVisible;
            }
            set
            {
                if (Equals(abyssPointsVisible, value)) return;
                abyssPointsVisible = value;

                OnPropertyChanged("AbyssPointsVisible");
            }
        }

            #endregion

            #region Random Bonus

        private Visibility randomBonusVisible;
        private string randomBonusText;
        private string randomBonusCharacters;
        private RandomBonus randomBonus;

        public Visibility RandomBonusVisible
        {
            get
            {
                return randomBonusVisible;
            }
            private set
            {
                if (Equals(randomBonusVisible, value)) return;

                randomBonusVisible = value;
                OnPropertyChanged("RandomBonusVisible");
            }
        }

        public string RandomBonusText
        {
            get
            {
                return randomBonusText;
            }
            set
            {
                if (Equals(randomBonusText, value)) return;

                randomBonusText = value;
                OnPropertyChanged("RandomBonusText");
            }
        }

        public string RandomBonusCharacters
        {
            get
            {
                return randomBonusCharacters;
            }
            set
            {
                if (Equals(randomBonusCharacters, value)) return;

                randomBonusCharacters = value;
                OnPropertyChanged("randomBonusCharacters");
            }
        }

        private RandomBonus RandomBonus
        {
            get
            {
                return randomBonus;
            }
            set
            {
                if (Equals(randomBonus, value)) return;
                randomBonus = value;

                CreateRandomBonusTable();
            }
        }

            #endregion

        #endregion

        #region Commands

        public RelayCommand<string> ChangeSelectionIndexCommand { get; private set; }
        public RelayCommand<string> OpenManastoneCommand { get; private set; }
        public RelayCommand<Button> DeleteManastoneCommand { get; private set; }
        public RelayCommand<Button> CopyManastoneCommand { get; private set; }
        public RelayCommand<string> PageSelectCommand { get; private set; }
        public RelayCommand OpenIdianCommand { get; private set; }
        public RelayCommand OpenRandomBonusCommand { get; private set; }
        public RelayCommand<string> OpenArmsfusionManastoneCommand { get; private set; }
        public RelayCommand<Button> CopyArmsfusionManastoneCommand { get; private set; }
        public RelayCommand<Button> DeleteArmsfusionManastoneCommand { get; private set; }
        public RelayCommand CopyIdToClipboardCommand { get; private set; }

        #endregion

        #region General Code

        private void WireCommands()
        {
            ChangeSelectionIndexCommand = new RelayCommand<string>(ChangeSelectionIndex) { IsEnabled = true };
            OpenManastoneCommand = new RelayCommand<string>(OpenManastone) { IsEnabled = true };
            DeleteManastoneCommand = new RelayCommand<Button>(DeleteManastone) { IsEnabled = true };
            CopyManastoneCommand = new RelayCommand<Button>(CopyManastone) { IsEnabled = true };
            PageSelectCommand = new RelayCommand<string>(PageSelect) { IsEnabled = true };
            OpenIdianCommand = new RelayCommand(OpenIdian) { IsEnabled = true };
            OpenRandomBonusCommand = new RelayCommand(OpenRandomBonus) { IsEnabled = true };
            OpenArmsfusionManastoneCommand = new RelayCommand<string>(OpenArmsfusionManastone) { IsEnabled = true };
            DeleteArmsfusionManastoneCommand = new RelayCommand<Button>(DeleteArmsfusionManastone) { IsEnabled = true };
            CopyArmsfusionManastoneCommand = new RelayCommand<Button>(CopyArmsfusionManastone) { IsEnabled = true };
            CopyIdToClipboardCommand = new RelayCommand(CopyIdToClipboard) { IsEnabled = true };
        }

        public ItemCardViewModel()
        {
            WireCommands();

            CardVisible = Visibility.Collapsed;
            PagesVisible = new ObservableCollection<Visibility>()
                           {
                               Visibility.Visible,
                               Visibility.Collapsed,
                               Visibility.Collapsed
                           };
            FirstPageChecked = true;
            Item = null;
            SaveItem = null;
            SaveItem2 = null;
            IsArmsfusionItem = false;

            Mediator.Instance.Register(o => GetItemSet((ItemSets)o), Messages.ItemSetSend);
        }

        public ItemCardViewModel(byte placeIndex)
            : this()
        {
            PlaceIndex = placeIndex;
        }

        public void LoadItem(DataRow row, bool isExtended = false)
        {
            if (!isExtended)
            {
                Item = row;
                _saveItem = row;
            }
            else
            {
                SaveItem2 = row;
            }
            
        }

        private bool CanVisible()
        {
            if (Item == null)
            {
                CardVisible = Visibility.Collapsed;
                return false;
            }

            CardVisible = Visibility.Visible;
            return true;
        }

        private void PageSelect(string pageIndex)
        {
            switch (pageIndex)
            {
                case "1":
                    PagesVisible[0] = Visibility.Visible;
                    PagesVisible[1] = Visibility.Collapsed;
                    PagesVisible[2] = Visibility.Collapsed;
                    break;
                case "2":
                    PagesVisible[0] = Visibility.Collapsed;
                    PagesVisible[1] = Visibility.Visible;
                    PagesVisible[2] = Visibility.Collapsed;
                    break;
                case "3":
                    PagesVisible[0] = Visibility.Collapsed;
                    PagesVisible[1] = Visibility.Collapsed;
                    PagesVisible[2] = Visibility.Visible;
                    break;
            }
        }

        private void CopyIdToClipboard()
        {
            if (string.IsNullOrEmpty(_itemId)) return;

            Clipboard.SetDataObject(_itemId);
        }

        internal void LoadCard()
        {
            if (Item == null)
            {
                CardVisible = Visibility.Collapsed;
                return;
            }
            
            if (!CanVisible()) return;

            SetItemsSelector();
            ResetAndFormCard();

            CardIsLoaded = true;
        }

        private void ChangeSelectionIndex(string index)
        {
            Item = index == "0" ? _saveItem : _saveItem2;
            ResetAndFormCard();
        }

        private void ResetAndFormCard()
        {
            SetMaxEnchantLevel();
            Enchant = 0;
            GodEnchantLevel = 0;
            idianMaxLevel = GetIdianMaxLevel();

            StatsList = new List<StatsValuesClass>();
            Idian = new Idian();
            ItemSet = null;

            GenerateCard();
        }

        private void SetItemsSelector()
        {
            if (SaveItem2 == null)
            {
                ItemsSelectorVisible = Visibility.Collapsed;
                return;
            }

            ItemsSelectorVisible = Visibility.Visible;
        }

        private void GenerateCard()
        {
            GenerateTopOfCard();

            AdditionalStats();
            SelectGroupOfMainStats();
            OtherStats();
        }

        private void AdditionalStats()
        {
            CreateEnchantTable();
            CreateManaStonesTable();
            CreateIdianTable();
            CreateRandomBonusTable();
            SetGodEnchant();
            GetItemSet(null);
            SetArmsfusion();
        }

        private void OtherStats()
        {
            CreateCoinsTable();

            ItemId = String.Format("[item: {0}]", _item["id"]);
        }

        private void UpdateEnchantList(
            char valueId,
            string stat,
            Single value,
            Single value2 = 0,
            EnchantStates state = EnchantStates.Value,
            string unit = "",
            string tips = "")
        {
            if (string.IsNullOrEmpty(stat)) return;

            StatsValuesClass statsValues = StatsList.Find(s => s.Stat == stat);
            if (statsValues == null)
            {
                statsValues = new StatsValuesClass(valueId, stat, value, value2, unit);
                StatsList.Add(statsValues);
            }
            else
            {
                statsValues.UpdateStatValue(valueId, value, value2, state, unit);
            }

            if (!string.IsNullOrEmpty(tips)) statsValues.Tips = tips;

            if (PlaceIndex > 0 && IsSendStats) SendStat(statsValues);
        }

        public void SendAllStats()
        {
            if (PlaceIndex == 0 || PlaceIndex == 16 || !IsSendStats) return;

            if (StatsList == null || StatsList.Count == 0)
            {
                Mediator.Instance.NotifyColleagues(Messages.CardStatsNullSend, PlaceIndex);
            }
            else
            {
                foreach (StatsValuesClass stat in StatsList)
                {
                    SendStat(stat);
                }
            }
        }

        private void SendStat(StatsValuesClass statsValues)
        {
            if (PlaceIndex == 0 || PlaceIndex == 16) return;
            
            KeyValuePair<byte, StatsValuesClass> statsOut = new KeyValuePair<byte, StatsValuesClass>(PlaceIndex, statsValues);
            Mediator.Instance.NotifyColleagues(Messages.CardStatsSend, statsOut);
        }

        public XElement GetCardElementForSaveToFile()
        {
            XElement xCard = new XElement("Place");

            xCard.Add(new XAttribute("Index", PlaceIndex));
            if (Item != null) xCard.Add(new XAttribute("Item", Item["Name"].ToString()));
            if (Enchant > 0) xCard.Add(new XAttribute("Enchant", Enchant));
            if (Idian != null && !String.IsNullOrEmpty(Idian.Name)) xCard.Add(new XAttribute("Idian", Idian.Name));
            if (RandomBonus != null) xCard.Add(new XAttribute("RandomBonus", RandomBonus.Id));
            if (GodEnchantLevel > 0) xCard.Add(new XAttribute("GodEnchant", GodEnchantLevel));

            if (Manastones != null)
            {
                foreach (ManaStone stone in Manastones)
                {
                    XElement xStone = new XElement("Manastone");
                    xStone.Add(new XAttribute("Index", stone.Index));
                    if (stone.Row != null) xStone.Add(new XAttribute("Name", stone.Row["Name"].ToString()));
                    xCard.Add(xStone);
                }
            }

            return xCard;
        }

        #endregion

        #region TopOfCard Code

        private void GenerateTopOfCard()
        {
            TranslateName = Item["translate" + DataModel.EngFix].ToString();

            string iconName = Item["icon_name"].ToString().Trim() + ".png";
            BitmapImage tIcon = new BitmapImage();
            Uri uri;
            if (File.Exists(DataModel.IconsDirectory + iconName))
            {
                Uri.TryCreate(DataModel.IconsDirectory + iconName, UriKind.RelativeOrAbsolute, out uri);
            }
            else
            {
                uri = new Uri("pack://application:,,,/CAION2;component/UI2/IconSlot.png", UriKind.Absolute);
            }
            tIcon.BeginInit();
            tIcon.UriSource = uri;
            tIcon.EndInit();
            Icon = tIcon;

            ItemTypeColorConverter itc = new ItemTypeColorConverter();
            TranslateColor = (SolidColorBrush)itc.Convert(Item["quality"], null, null, null);

            ItemType = GetItemType(Item["name"].ToString())
                       + GetItemRank(Item["item_type"].ToString());
            ItemSpeed = GetWeaponSpeedText();

            ItemLevel = GetLevelNeedText();
            ItemSoul = Item["soul_bind"].ToString() == "TRUE" ? Resources.CardPutSoul : "";

            ItemExchange = GetExchangeInfo();
            GetAdditionalExchangeInfo();
        }

        private static string GetItemType(string value)
        {
            try
            {
                return ClassItem.Types.FirstOrDefault(localType => value.ToUpper().Contains(localType.Key)).Value;
            }
            catch
            {
                return "";
            }
        }

        private static string GetItemRank(string value)
        {
            try
            {
                string rank = ClassItem.Ranks.FirstOrDefault(localType => value.ToUpper().Contains(localType.Key)).Value;
                if (!string.IsNullOrEmpty(rank)) rank = " (" + rank + ")";
                return rank;
            }
            catch
            {
                return "";
            }
        }

        private string GetWeaponSpeedText()
        {
            if (!Item.Table.Columns.Contains("weapon_type")) return "";

            if (String.IsNullOrEmpty(Item["weapon_type"].ToString())) return "";

            Int16 speed = Convert.ToInt16(Item["attack_delay"]);
            Byte hitCount = Convert.ToByte(Item["hit_count"]);

            string result;

            switch (speed)
            {
                case 1200:
                    result = String.Format(Resources.CardWeaponSpeed1, hitCount);
                    break;
                case 1400:
                case 1500:
                    result = String.Format(Resources.CardWeaponSpeed2, hitCount);
                    break;
                case 2000:
                case 2200:
                    result = String.Format(Resources.CardWeaponSpeed3, hitCount);
                    break;
                case 2400:
                case 2800:
                    result = String.Format(Resources.CardWeaponSpeed4, hitCount);
                    break;
                default:
                    result = String.Format(Resources.CardWeaponSpeed0, hitCount);
                    break;
            }

            switch (Item["attack_type"].ToString())
            {
                case "magical_water":
                    result += "\n(" + Resources.Stats_AttackType_magical_water + ")";
                    break;
                case "magical_fire":
                    result += "\n(" + Resources.Stats_AttackType_magical_fire + ")";
                    break;
            }

            return result;
        }

        private string GetLevelNeedText()
        {
            Byte level = Convert.ToByte(Item["level"].ToString());
            ItemLevelTag = "";

            if (Item.Table.Columns["warrior"] == null) return String.Format(Resources.Card_Level, level);

            List<string> avaClasses = new List<string>();
            if (Item["warrior"].ToString() != "0") avaClasses.Add(Resources.Class_Warrior);
            if (Item["scout"].ToString() != "0") avaClasses.Add(Resources.Class_Scout);
            if (Item["mage"].ToString() != "0") avaClasses.Add(Resources.Class_Mage);
            if (Item["cleric"].ToString() != "0") avaClasses.Add(Resources.Class_Cleric);
            if (Item["engineer"].ToString() != "0") avaClasses.Add(Resources.Class_Engineer);
            if (Item["artist"].ToString() != "0") avaClasses.Add(Resources.Class_Artist);

            if (Item["fighter"].ToString() != "0") avaClasses.Add(Resources.Class_Fighter);
            if (Item["knight"].ToString() != "0") avaClasses.Add(Resources.Class_Knight);

            if (Item["assassin"].ToString() != "0") avaClasses.Add(Resources.Class_Assassin);
            if (Item["ranger"].ToString() != "0") avaClasses.Add(Resources.Class_Ranger);

            if (Item["wizard"].ToString() != "0") avaClasses.Add(Resources.Class_Wizard);
            if (Item["elementalist"].ToString() != "0") avaClasses.Add(Resources.Class_Elementalist);

            if (Item["chanter"].ToString() != "0") avaClasses.Add(Resources.Class_Chanter);
            if (Item["priest"].ToString() != "0") avaClasses.Add(Resources.Class_Priest);

            if (Item["gunner"].ToString() != "0") avaClasses.Add(Resources.Class_Gunner);
            if (Item["bard"].ToString() != "0") avaClasses.Add(Resources.Class_Bard);
            //if (Items[_currentItemIndex]["rider"].ToString() != "0") avaClasses.Add(Resources.CardRider);


            if (avaClasses.Count < 4) ItemLevelTag = "1";

            if (avaClasses.Count > 3) return String.Format(Resources.Card_Level, level);


            if (avaClasses.Count == 3)
            {
                if (avaClasses.Contains(Resources.Class_Warrior)) return String.Format(Resources.CardLevelUp, Resources.Class_Warrior, level);

                if (avaClasses.Contains(Resources.Class_Scout)) return String.Format(Resources.CardLevelUp, Resources.Class_Scout, level);

                if (avaClasses.Contains(Resources.Class_Mage)) return String.Format(Resources.CardLevelUp, Resources.Class_Mage, level);

                if (avaClasses.Contains(Resources.Class_Cleric)) return String.Format(Resources.CardLevelUp, Resources.Class_Cleric, level);
            }

            if (avaClasses.Count == 2)
            {
                if (avaClasses.Contains(Resources.Class_Engineer)) return String.Format(Resources.CardLevelUp, Resources.Class_Engineer, level);

                if (avaClasses.Contains(Resources.Class_Artist)) return String.Format(Resources.CardLevelUp, Resources.Class_Artist, level);
            }

            if (avaClasses.Count == 1)
            {
                if (avaClasses.Contains(Resources.Class_Fighter)) return String.Format(Resources.CardLevelUp, Resources.Class_Fighter, level);

                if (avaClasses.Contains(Resources.Class_Knight)) return String.Format(Resources.CardLevelUp, Resources.Class_Knight, level);

                if (avaClasses.Contains(Resources.Class_Assassin)) return String.Format(Resources.CardLevelUp, Resources.Class_Assassin, level);

                if (avaClasses.Contains(Resources.Class_Ranger)) return String.Format(Resources.CardLevelUp, Resources.Class_Ranger, level);

                if (avaClasses.Contains(Resources.Class_Wizard)) return String.Format(Resources.CardLevelUp, Resources.Class_Wizard, level);

                if (avaClasses.Contains(Resources.Class_Elementalist)) return String.Format(Resources.CardLevelUp, Resources.Class_Elementalist, level);

                if (avaClasses.Contains(Resources.Class_Chanter)) return String.Format(Resources.CardLevelUp, Resources.Class_Chanter, level);

                if (avaClasses.Contains(Resources.Class_Priest)) return String.Format(Resources.CardLevelUp, Resources.Class_Priest, level);

                if (avaClasses.Contains(Resources.Class_Gunner)) return String.Format(Resources.CardLevelUp, Resources.Class_Gunner, level);

                if (avaClasses.Contains(Resources.Class_Bard)) return String.Format(Resources.CardLevelUp, Resources.Class_Bard, level);
            }

            return String.Format(Resources.Card_Level, level);
        }

        private string GetExchangeInfo()
        {
            return Item["can_exchange"].ToString() == "FALSE" ? Resources.CardCantExchange : "";
        }

        private void GetAdditionalExchangeInfo()
        {
            ExchangeVisible = new ObservableCollection<Visibility>
                              {
                                  Item["can_sell_to_npc"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item[
                                      "can_deposit_to_character_warehouse"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item[
                                      "can_deposit_to_account_warehouse"].ToString(
                                          ) == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item[
                                      "can_deposit_to_guild_warehouse"].ToString()
                                  == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item["can_proc_enchant"]
                                      .ToString() == "FALSE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item["cannot_extraction"]
                                      .ToString() == "TRUE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item["can_ap_extraction"]
                                      .ToString() == "TRUE"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item["extract_skin_type"]
                                      .ToString() == "2"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed,
                                  Item["cannot_changeskin"]
                                      .ToString() == "1"
                                      ? Visibility.Visible
                                      : Visibility.Collapsed
                              };


        }

        #endregion

        #region Stats Code

        private void SelectGroupOfMainStats()
        {
            if (Item.Table.Columns.Contains("weapon_type")
                && Item["weapon_type"].ToString() != "")
            {
                UpdateStatsFromWeapon();
                UpdateStatsFromBonus();
                
                ShowMainStatsWeaponTable();
                ShowFullStatsTable();
            }
            else if (Item.Table.Columns.Contains("armor_type")
                     && !string.IsNullOrEmpty(Item["armor_type"].ToString())
                     && Item["armor_type"].ToString() != "no_armor"
                     && Item["equipment_slots"].ToString() != "wing")
            {
                UpdateStatsFromArmor();
                UpdateStatsFromBonus();
                
                ShowMainStatsArmorTable();
                ShowFullStatsTable();
            }
            else if (Item["name"].ToString().Substring(0, 6) == "shield"
                     && Item["equipment_slots"].ToString() == "sub")
            {
                UpdateStatsFromShield();
                UpdateStatsFromBonus();
                
                ShowMainStatsShieldTable();
                ShowFullStatsTable();
            }
            else if (Item["equipment_slots"].ToString() == "head"
                     || Item["equipment_slots"].ToString() == "wing")
            {
                UpdateStatsFromArmor();
                UpdateStatsFromBonus();

                ShowMainStatsArmorTable();
                ShowFullStatsTable();
            }
            else if (Item["activation_skill"].ToString().Contains("food")
                     || Item["name"].ToString().Contains("potion_")
                     || Item["name"].ToString().Contains("remedy_"))
            {
                UpdateAndShowStatsFromFood();
            }
            else if (JewelMarks.Contains(Item["equipment_slots"].ToString()))
            {
                UpdateStatsFromJewel();
                UpdateStatsFromBonus();

                ShowMainStatsJewelsTable();
                ShowFullStatsTable();
            }
            else
            {
                FullCharacters = "";
                FullCharacters2 = "";
                MainCharacters = "";
            }

            ShowBonusStatsTable();
        }

        private void UpdateStatsFromWeapon()
        {           
            UpdateEnchantList(
                'x',
                "phyattack",
                (int)Item["min_damage"],
                (int)Item["max_damage"],
                tips: Item["weapon_type"].ToString());


            if (Item["magical_skill_boost"].ToString() != "0")
            {
                UpdateEnchantList('x', "magicalskillboost", (int)Item["magical_skill_boost"]);
            }

            UpdateEnchantList('x', "attackdelay", Convert.ToSingle(Item["attack_delay"]) / 1000);
            
            if (Item["hit_accuracy"].ToString() != "" && Item["hit_accuracy"].ToString() != "0") UpdateEnchantList('x', "hitaccuracy", (int)Item["hit_accuracy"]);

            if (Item["critical"].ToString() != "" && Item["critical"].ToString() != "0") UpdateEnchantList('x', "critical", (int)Item["critical"]);

            if (Item["parry"].ToString() != "" && Item["parry"].ToString() != "0") UpdateEnchantList('x', "parry", (int)Item["parry"]);

            if (Item["magical_hit_accuracy"].ToString() != "" && Item["magical_hit_accuracy"].ToString() != "0") UpdateEnchantList('x', "magicalhitaccuracy", (int)Item["magical_hit_accuracy"]);
        }

        private void UpdateStatsFromArmor()
        {
            if (Item.Table.Columns.Contains("physical_defend")
                && !DBNull.Value.Equals(Item["physical_defend"])
                && Convert.ToUInt32(Item["physical_defend"]) != 0) UpdateEnchantList('x', "physicaldefend", (int)Item["physical_defend"]);

            if (Item.Table.Columns.Contains("magical_skill_boost_resist")
                && !string.IsNullOrEmpty(Item["magical_skill_boost_resist"].ToString()))
                UpdateEnchantList(
                    'x',
                    "magicalskillboostresist",
                    (int)Item["magical_skill_boost_resist"]);

            if (Item.Table.Columns.Contains("magical_resist")
                && !DBNull.Value.Equals(Item["magical_resist"])
                && Convert.ToUInt32(Item["magical_resist"]) != 0) UpdateEnchantList('x', "magicalresist", (int)Item["magical_resist"]);

            if (Item.Table.Columns.Contains("dodge")
                && !DBNull.Value.Equals(Item["dodge"])
                && Convert.ToUInt32(Item["dodge"]) != 0) UpdateEnchantList('x', "dodge", (int)Item["dodge"]);
        }

        private void UpdateStatsFromShield()
        {
            if (Convert.ToUInt32(Item["block"]) != 0) UpdateEnchantList('x', "block", (int)Item["block"]);

            if (Convert.ToUInt32(Item["damage_reduce"]) != 0) UpdateEnchantList('x', "damagereduce", (int)Item["damage_reduce"]);
        }

        private void UpdateAndShowStatsFromFood()
        {
            Dictionary<string, string> fStats = new Dictionary<string, string>();

            DataRow result = DataModel.GetRowAtName(
                "Foods",
                Item["name"].ToString(),
                "translate" + DataModel.EngFix);

            fStats.Add(result["translate"].ToString(), "");

            ShowMainStatsFoodTable(fStats, false);
        }

        private void UpdateStatsFromJewel()
        {
            if (Convert.ToUInt32(Item["magical_resist"]) != 0) UpdateEnchantList('x', "magicalresist", (int)Item["magical_resist"]);

            if (!string.IsNullOrEmpty(Item["magical_skill_boost_resist"].ToString()))
                UpdateEnchantList(
                    'x',
                    "magicalskillboostresist",
                    (int)Item["magical_skill_boost_resist"]);
        }

        private void ShowFullStatsTable()
        {
            FullCharacters = "";
            FullCharacters2 = "";

            if (StatsList == null || StatsList.Count == 0) return;

            foreach (StatsValuesClass stat in StatsList.Where(stat => Math.Abs(stat.BasicValue + stat.Sum()) > 0))
            {
                FullCharacters += String.Format("{0}\n", stat.Translate);
                FullCharacters2 += String.Format("{0}{1}\n", stat.BasicValueText(), stat.SumValueText());
            }
        }

        private void ShowMainStatsWeaponTable()
        {
            MainCharacters = "";

            if (StatsList == null || StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();

            StatsValuesClass aStat = StatsList.Find(s => s.Stat == "phyattack");
            MainCharacters = String.Format(
                "{0,-20}[color=" + AppearanceManager.Current.AccentColor + "] {1}[/color]\n",
                aStat.Translate,
                aStat.BasicValueText());

            aStat = StatsList.Find(s => s.Stat == "magicalskillboost");
            if (aStat != null)
            {
                MainCharacters += converter.Convert(new KeyValuePair<string, float>(aStat.Translate, aStat.BasicValue),
                                                   null,
                                                   null,
                                                   null) + "\n";
            }


            List<string> mainStats = new List<string>
                                     {
                                         "attackdelay",
                                         "hitaccuracy",
                                         "critical",
                                         "parry",
                                         "magicalhitaccuracy"
                                     };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                   null,
                                                   null,
                                                   null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsArmorTable()
        {
            MainCharacters = "";

            if (StatsList == null || StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string>
                                     {
                                         "physicaldefend",
                                         "magicalskillboostresist",
                                         "magicalresist",
                                         "dodge"
                                     };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsShieldTable()
        {
            MainCharacters = "";

            if (StatsList == null || StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string> { "block", "damagereduce" };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowMainStatsFoodTable(Dictionary<string, string> fStats, bool isShape)
        {
            MainCharacters = "";
            FullCharacters = "";
            FullCharacters2 = "";

            if (fStats == null || fStats.Count == 0) return;

            foreach (KeyValuePair<string, string> stat in fStats)
            {
                if (isShape)
                {
                    MainCharacters += stat.Key + "\n" + stat.Value;
                }
                else
                {
                    MainCharacters += stat.Key + " " + stat.Value + "\n";
                }
            }

            FullCharacters = MainCharacters;
        }

        private void ShowMainStatsJewelsTable()
        {
            MainCharacters = "";

            if (StatsList == null || StatsList.Count == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            List<string> mainStats = new List<string> { "magicalresist", "magicalskillboostresist" };

            int i = 0;
            string caret = "\t  ";
            foreach (
                StatsValuesClass stat in StatsList.Where(stat => mainStats.Contains(stat.Stat) && Math.Abs(stat.BasicValue) > 0))
            {
                MainCharacters += converter.Convert(new KeyValuePair<string, float>(stat.Translate, stat.BasicValue),
                                                    null,
                                                    null,
                                                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        private void ShowBonusStatsTable()
        {
            BonusCharacters = "";

            if (StatsList == null || StatsList.Count == 0) return;

            BonusTextConverter converter = new BonusTextConverter();

            int i = 0;
            string caret = "\t  ";
            foreach (StatsValuesClass stat in StatsList.Where(stat => Math.Abs(stat.BonusValue) > 0))
            {
                string[] signs = new string[2];
                if (stat.BonusValue < 0)
                {
                    signs[0] = "";
                }
                else
                {
                    signs[0] = "+";
                }

                if (stat.Unit.Length > 0)
                {
                    signs[1] = stat.Unit;
                }
                else
                {
                    signs[1] = "";
                }
                

                BonusCharacters += converter.Convert(
                    new KeyValuePair<string, float>(stat.Translate, stat.BonusValue),
                    null,
                    signs,
                    null) + caret;

                caret = i % 2 == 0 ? "\n" : "\t  ";
                i++;
            }
        }

        #endregion

        #region Enchantment Code

        private void CreateEnchantTable()
        {
            if (MaximumEnchant == 0 || IsArmsfusionItem)
            {
                Enchant = 0;
                EnchantVisible = Visibility.Collapsed;
            }
            else
            {
                EnchantVisible = Enum.IsDefined(
                    typeof(ClassEnchantment.EnchantSlots),
                    Item["equipment_slots"].ToString())
                    ? Visibility.Visible
                    : Visibility.Collapsed;
            }
        }

        private void SetMaxEnchantLevel()
        {
            if (!Item.Table.Columns.Contains("max_enchant_value"))
            {
                MaximumEnchant = 0;
            }
            else
            {
                MaximumEnchant = Item["max_enchant_value"].ToString() != ""
                    ? Convert.ToByte(Item["max_enchant_value"])
                    : Convert.ToByte(0);
            }
        }

        #region EnchantmentKoeffs

        private int GetEnchantmentHPKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].Hp;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].Hp;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].Hp;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].Hp;
                    break;
            }

            return enKoeff * Enchant;
        }

        private int GetEnchantmentMagicalBlockKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].MagicalBlock;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].MagicalBlock;
                    break;
            }

            return enKoeff * Enchant;
        }

        private int GetEnchantmentDefenceKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enKoeff = 0;

            switch (Item["armor_type"].ToString())
            {
                case "plate":
                    enKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "chain":
                    enKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "leather":
                    enKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].PhysicalDefend;
                    break;
                case "robe":
                    enKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].PhysicalDefend;
                    break;
            }

            return enKoeff * Enchant;
        }

        private int GetEnchantmentDefenceResistKoeff(ClassEnchantment.EnchantSlots slot)
        {
            SByte enchantKoeff = 0;

            switch (Item["armor_type"].ToString())
            {
                case "plate":
                    enchantKoeff = ClassEnchantment.PlateEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "chain":
                    enchantKoeff = ClassEnchantment.ChainEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "leather":
                    enchantKoeff = ClassEnchantment.LeatherEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
                case "robe":
                    enchantKoeff = ClassEnchantment.RobeEnchant[slot.ToString()].PhysicalCriticalReduceRate;
                    break;
            }

            return enchantKoeff * Enchant;
        }

        private int GetEnchantmentAttackKoeff()
        {
            if (String.IsNullOrEmpty(Item["weapon_type"].ToString())) return 0;

            sbyte enKoeff =
                ClassEnchantment.WeaponEnchant[Item["weapon_type"].ToString()].MainHandAttack;
            return enKoeff * Enchant;
        }

        private int GetEnchantmentMagicBoostKoeff()
        {
            if (String.IsNullOrEmpty(Item["weapon_type"].ToString())) return 0;

            sbyte enKoeff =
                ClassEnchantment.WeaponEnchant[Item["weapon_type"].ToString()].MagicalSkillBoost;
            return enKoeff * Enchant;
        }

        private int GetEnchantmentDamageReduceKoeff()
        {
            if (!Item["name"].ToString().ToLower().Contains("shield")) return 0;

            sbyte enKoeff = ClassEnchantment.ShieldEnchant["shield"].DamageReduce;
            int res = enKoeff * Enchant;
            if (res > 20) res = 20;
            return res;
        }

        private int GetEnchantmentBlockKoeff()
        {
            if (!Item["name"].ToString().ToLower().Contains("shield")) return 0;

            sbyte enKoeff = ClassEnchantment.ShieldEnchant["shield"].Block;
            if (Enchant > 10) return enKoeff * (Enchant - 10);
            return 0;
        }

        #endregion

        private void GetEnchantStats()
        {
            ClassEnchantment.EnchantSlots enchantSlot;
            if (!Enum.TryParse(Item["equipment_slots"].ToString(), true, out enchantSlot)) return;

            int eValue;
            switch ((int)enchantSlot)
            {
                case 0:
                    eValue = GetEnchantmentDefenceKoeff(enchantSlot);
                    UpdateEnchantList('e', "physicaldefend", eValue);

                    eValue = GetEnchantmentHPKoeff(enchantSlot);
                    UpdateEnchantList('e', "maxhp", eValue);

                    eValue = GetEnchantmentDefenceResistKoeff(enchantSlot);
                    UpdateEnchantList('e', "physicalcriticalreducerate", eValue);

                    eValue = GetEnchantmentMagicalBlockKoeff(enchantSlot);
                    UpdateEnchantList('e', "magicalblock", eValue);
                    break;
                case 1:
                    eValue = GetEnchantmentAttackKoeff();
                    UpdateEnchantList('e', "phyattack", eValue);

                    eValue = GetEnchantmentMagicBoostKoeff();
                    UpdateEnchantList('e', "magicalskillboost", eValue);

                    eValue = GetEnchantmentDamageReduceKoeff();
                    UpdateEnchantList('e', "damagereduce", eValue);

                    eValue = GetEnchantmentBlockKoeff();
                    UpdateEnchantList('e', "block", eValue);
                    break;
            }
        }

        #endregion

        #region ManaStones Code

        private void CreateManaStonesTable()
        {
            if (Item["cannot_matter_option"].ToString() == "TRUE")
            {
                ManastonesVisible = Visibility.Collapsed;
                return;
            }

            byte normalSlots;
            byte bonusSlots;
            byte specialSlots;
            GetManaStonesCount(out normalSlots, out bonusSlots, out specialSlots);

            if (normalSlots + bonusSlots + specialSlots == 0)
            {
                ManastonesVisible = Visibility.Collapsed;
                return;
            }

            ManastonesVisible = Visibility.Visible;
            byte index = 1;

            Manastones = new ObservableCollection<ManaStone>();
            for (int i = 0; i < specialSlots; i++)
            {
                Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Special, index));
                index++;
            }
            for (int i = 0; i < normalSlots; i++)
            {
                Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Normal, index));
                index++;
            }
            for (int i = 0; i < bonusSlots; i++)
            {
                Manastones.Add(new ManaStone(ManaStone.ManaStoneType.Bonus, index));
                index++;
            }

            for (int i = 0; i < 6 - normalSlots - bonusSlots - specialSlots; i++)
            {
                Manastones.Add(new ManaStone(ManaStone.ManaStoneType.None, index));
                index++;
            }

            ManastonesMaxLevel = GetManaStonesMaxLevel();

            ManastoneText = String.Format(Resources.Manastones_LevelInfo, ManastonesMaxLevel);
        }

        private void GetManaStonesCount(out byte normalCount, out byte bonusCount, out byte specialCount)
        {
            normalCount = 0;
            bonusCount = 0;
            specialCount = 0;

            if (!Item.Table.Columns.Contains("option_slot_value")
                || String.IsNullOrEmpty(Item["option_slot_value"].ToString())) return;

            normalCount = Convert.ToByte(Item["option_slot_value"].ToString());

            if (!string.IsNullOrEmpty(Item["option_slot_bonus"].ToString())) bonusCount = Convert.ToByte(Item["option_slot_bonus"].ToString());

            if (!string.IsNullOrEmpty(Item["special_slot_value"].ToString())) specialCount = Convert.ToByte(Item["special_slot_value"].ToString());

            if (normalCount + bonusCount + specialCount > 6)
            {
                normalCount = (byte)(6 - bonusCount - specialCount);
            }
        }

        private byte GetManaStonesMaxLevel()
        {
            byte level = Convert.ToByte(Item["level"].ToString());

            if (level <= 10)
            {
                return 20;
            }
            if (level <= 20)
            {
                return 30;
            }
            if (level <= 30)
            {
                return 40;
            }
            if (level <= 40)
            {
                return 50;
            }
            return (byte)(level <= 50 ? 60 : 70);
        }

        private void OpenManastone(string stoneNumber)
        {
            byte stoneIndex = Convert.ToByte(stoneNumber);

            ManastonePage mp = new ManastonePage();
            ManastonesDialogViewModel mpvm = (ManastonesDialogViewModel)mp.DataContext;

            ModernDialog md = new ModernDialog { Content = mp, Title = Resources.Manastones_DialogTitle };

            mpvm.CurrentManaStone = Manastones[stoneIndex];
            mpvm.MaxLevel = ManastonesMaxLevel;
            mpvm.Type = Manastones[stoneIndex].SlotType;
            mpvm.Index = Manastones[stoneIndex].Index;
            mpvm.Dialog = md;

            md.MaxWidth = 800;
            md.Buttons = new[] { md.OkButton, md.CancelButton };
            md.ShowDialog();

            if (md.GetDialogResult == MessageBoxResult.Cancel) return;

            Manastones[stoneIndex] = mpvm.CurrentManaStone.CloneLite(
                Manastones[stoneIndex].SlotType,
                Manastones[stoneIndex].Index);

            if (ReferenceEquals(md.Tag, "CopyManaStone"))
            {
                CopyManaStoneToAllSlots(mpvm.CurrentManaStone);
            }
            else
            {
                UpdateManastoneStats(Manastones[stoneIndex], EnchantStates.Plus);
            }
        }

        private void CopyManaStoneToAllSlots(ManaStone sourceManastone)
        {
            for (int i = 0; i < Manastones.Count; i++)
            {
                if (Manastones[i].Visible != Visibility.Visible || Manastones[i].Index == sourceManastone.Index) continue;

                if (((sourceManastone.SlotType != ManaStone.ManaStoneType.Normal
                      && sourceManastone.SlotType != ManaStone.ManaStoneType.Bonus)
                     || (Manastones[i].SlotType != ManaStone.ManaStoneType.Normal
                         && Manastones[i].SlotType != ManaStone.ManaStoneType.Bonus))
                    && (sourceManastone.SlotType != ManaStone.ManaStoneType.Special
                        || Manastones[i].SlotType != ManaStone.ManaStoneType.Special)) continue;

                Manastones[i] = sourceManastone.CloneLite(Manastones[i].SlotType, Manastones[i].Index);

                UpdateManastoneStats(Manastones[i], EnchantStates.Plus);
            }


        }

        private void DeleteManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (Manastones[index].Row == null) return;

            UpdateManastoneStats(Manastones[index], EnchantStates.Minus);
            Manastones[index] = new ManaStone(Manastones[index].SlotType, Manastones[index].Index);
        }

        private void CopyManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (Manastones[index].Row == null) return;

            CopyManaStoneToAllSlots(Manastones[index]);
        }

        private void UpdateManastoneStats(ManaStone stone, EnchantStates state)
        {
            for (int i = 1; i < 6; i++)
            {
                if (stone.Row == null || string.IsNullOrEmpty(stone.Row["stat_enchant_type" + i].ToString())) continue;
                UpdateEnchantList(
                    'm',
                    stone.Row["stat_enchant_type" + i].ToString().ToLower(),
                    Convert.ToInt32(stone.Row["stat_enchant_value" + i]),
                    0,
                    state);
            }

            ShowFullStatsTable();
        }

        public void LoadManastone(byte index, string manastoneName)
        {
            Manastones[index] = new ManaStone(
                DataModel.GetRowAtName("MagicStones", manastoneName),
                Manastones[index].SlotType) { Index = (byte)(index + 1) };
            UpdateManastoneStats(Manastones[index], EnchantStates.Plus);
        }

        #endregion

        #region Bonus Code

        private void UpdateStatsFromBonus()
        {
            for (byte i = 1; i < 13; i++)
            {
                string newUnit = "";
                KeyValuePair<String, Single> stat =
                    CardStat.GetStat(Item["bonus_attr" + i].ToString());

                if (string.IsNullOrEmpty(stat.Key)) continue;
                if (Item["bonus_attr" + i].ToString().Contains("%")) newUnit = "%";
                UpdateEnchantList('b', stat.Key, stat.Value, unit: newUnit);
            }
        }

        #endregion

        #region Idian Code

        private void CreateIdianTable()
        {
            if (!Item.Table.Columns.Contains("can_polish") || IsArmsfusionItem || PlaceIndex == 2)
            {
                IdianVisible = Visibility.Collapsed;
            }
            else
            {
                IdianVisible = Item["can_polish"].ToString() == "TRUE"
                    ? Visibility.Visible
                    : Visibility.Collapsed;
                if (IdianVisible != Visibility.Visible) return;
            }

            IdianText = Resources.Idian_DefaultText;
            IdianCharacters = string.Format(Resources.Idian_LevelInfo, idianMaxLevel) + "\n\n";

            if (String.IsNullOrEmpty(Idian.Name))
            {
                IdianCharacters += Resources.Idian_NoEffect;
            }
            else
            {
                ItemTypeColorConverter converter = new ItemTypeColorConverter();
                IdianText = string.Format(
                    Resources.Idian_InsertedIdian,
                    Idian.Translate,
                    converter.Convert(Idian.Quality, null, "TextColor", null));

                IdianRandomTextConverter converter2 = new IdianRandomTextConverter();
                IdianCharacters += converter2.Convert(Idian.Random1, null, "AccentColor", null);

                string iBonus2 =  converter2.Convert(Idian.Random2, null, "AccentColor", null).ToString() ;
                if (!string.IsNullOrWhiteSpace(iBonus2)) IdianCharacters += ", " + iBonus2;

                iBonus2 = converter2.Convert(Idian.Random3, null, "AccentColor", null).ToString();
                if (!string.IsNullOrWhiteSpace(iBonus2)) IdianCharacters += ", " + iBonus2;
            }
        }

        private byte GetIdianMaxLevel()
        {
            byte level = Convert.ToByte(Item["level"].ToString());

            if (level <= 10)
            {
                return 20;
            }
            if (level <= 20)
            {
                return 30;
            }
            if (level <= 30)
            {
                return 40;
            }
            if (level <= 40)
            {
                return 50;
            }
            return (byte)(level <= 50 ? 60 : 70);
        }

        private void OpenIdian()
        {
            IdianPage ip = new IdianPage();
            IdianDialogViewModel ipvm = (IdianDialogViewModel)ip.DataContext;

            ModernDialog md = new ModernDialog { Content = ip, Title = Resources.Idian_DialogTitle };

            ipvm.Idian = Idian;
            ipvm.MaxLevel = idianMaxLevel;
            ipvm.Dialog = md;
            md.MaxWidth = 900;
            md.Buttons = new[] { md.OkButton, md.CancelButton };
            md.ShowDialog();

            if (md.GetDialogResult == MessageBoxResult.Cancel) return;

            Idian = ipvm.Idian;

            GetIdianStats();
        }

        private void GetIdianStats()
        {
            if (String.IsNullOrEmpty(Idian.Name))
            {
                foreach (StatsValuesClass enchantClass in StatsList)
                {
                    if (Math.Abs(enchantClass.IdianValue - 0) > 0)
                    {
                        UpdateEnchantList('i', enchantClass.Stat, enchantClass.IdianValue, 0, EnchantStates.Minus);
                    }

                    enchantClass.IdianValue = 0;
                }
            }

            UpdateEnchantList('i', Idian.Random1.Key, Idian.Random1.Value);
            UpdateEnchantList('i', Idian.Random2.Key, Idian.Random2.Value);
            UpdateEnchantList('i', Idian.Random3.Key, Idian.Random3.Value);
            UpdateEnchantList('i', Idian.Random4.Key, Idian.Random4.Value);
            UpdateEnchantList('i', Idian.Random5.Key, Idian.Random5.Value);
            UpdateEnchantList('i', Idian.Random6.Key, Idian.Random6.Value);
            UpdateEnchantList('i', Idian.Random7.Key, Idian.Random7.Value);
            UpdateEnchantList('i', Idian.Random8.Key, Idian.Random8.Value);

            ShowFullStatsTable();
        }

        public void LoadIdian(string idianName)
        {
            Idian = new Idian(idianName);
            GetIdianStats();
        }

        #endregion

        #region Coins Code

        private void CreateCoinsTable()
        {
            AbyssPointsVisible = new List<Visibility>(2);

            if (!string.IsNullOrEmpty(Item["extra_currency_item"].ToString()))
            {
                DataRow row = DataModel.GetRowAtName(
                    "Allitems_Coins",
                    Item["extra_currency_item"].ToString(),
                    filterField: "coin_name");

                if (row != null)
                {
                    ExtraCurrencyIcon = row["icon_name"].ToString();
                    ExtraCurrencyName = row["translate" + DataModel.EngFix].ToString();
                    AbyssPointsVisible.Add(Visibility.Visible);
                }
                else
                {
                    AbyssPointsVisible.Add(Visibility.Collapsed);
                }
            }
            else
            {
                ExtraCurrencyIcon = "";
                ExtraCurrencyName = "";
                AbyssPointsVisible.Add(Visibility.Collapsed); 
            }

            if (Item.Table.Columns.Contains("abyss_point"))
            {
                AbyssPointsVisible.Add(string.IsNullOrEmpty(Item["abyss_point"].ToString())
                                        ? Visibility.Collapsed : Visibility.Visible);
            }
            else
            {
                AbyssPointsVisible.Add(Visibility.Collapsed);
            }

            OnPropertyChanged("AbyssPointsVisible");

            Coins = DataModel.GetCoins(Item["name"].ToString());
        }

        #endregion

        #region God Enchant Code

        private void CreateGodEnchantStats()
        {
            GodEnchantStats = new List<KeyValuePair<string, float>>();

            for (int i = 1; i <= 4; i++)
            {
                KeyValuePair<string, float> stat = CardStat.GetStat(Item["bonus_attr_a"+i].ToString());
                GodEnchantStats.Add(new KeyValuePair<string, float>(stat.Key, stat.Value));
            }
            for (int i = 1; i <= 4; i++)
            {
                KeyValuePair<string, float> stat = CardStat.GetStat(Item["bonus_attr_b" + i].ToString());
                GodEnchantStats.Add(new KeyValuePair<string, float>(stat.Key, stat.Value));
            }
        }

        private void SetGodEnchant()
        {
            if (Item.Table.Columns["charge_level"] == null 
                || string.IsNullOrEmpty(Item["charge_level"].ToString()))
            {
                GodEnchantVisible = Visibility.Collapsed;
                GodEnchantLevel = 0;
                GodEnchantStats = null;

                GodEnchantCharactersLevel1 = "";
                GodEnchantCharactersLevel2 = "";

                return;
            }

            CreateGodEnchantStats();
            if (IsArmsfusionItem)
            {
                GodEnchantVisible = Visibility.Collapsed;
                return;
            }
            
            GodEnchantVisible = Visibility.Visible;
            GodEnchantMaxLevel = Convert.ToByte(Item["charge_level"]);

            CreateGodEnchantTable();
        }

        private void CreateGodEnchantTable()
        {
            GodEnchantCharactersLevel1 = "";
            GodEnchantCharactersLevel2 = "";

            if (GodEnchantMaxLevel == 0) return;

            CharacterTextConverter converter = new CharacterTextConverter();
            GodEnchantCharactersLevel1 = string.Format(Resources.GodEnchant_CondiEffect, "1") + "\n";

            SetGodEnchantCharactersOpacity();

            string caret = "\t  ";
            for (int i = 0; i <= 3; i++)
            {
                GodEnchantCharactersLevel1 += converter.Convert(GodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }

            if (GodEnchantMaxLevel <= 1) return;

            GodEnchantCharactersLevel2 = string.Format(Resources.GodEnchant_CondiEffect, "2") + "\n";

            caret = "\t";
            for (int i = 4; i <= 7; i++)
            {
                GodEnchantCharactersLevel2 += converter.Convert(GodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
        }

        public void SetGodEnchantLevel(string sLevel)
        {
            GodEnchantLevel = Convert.ToByte(sLevel);
        }

        private void SetGodEnchantCharactersOpacity()
        {
            GodEnchantLevelsOpacity = new[] { 0.4f, 0.4f };

            if (GodEnchantLevel > 0) GodEnchantLevelsOpacity[0] = 1;
            if (GodEnchantLevel > 1) GodEnchantLevelsOpacity[1] = 1;

            OnPropertyChanged("GodEnchantLevelsOpacity");
        }

        private void GetGodEnchantStats()
        {
            if (godEnchantLevel == 0)
            {
                foreach (StatsValuesClass enchantClass in StatsList.Where(enchantClass => Math.Abs(enchantClass.GodEnchantValue - 0) > 0))
                {
                    UpdateEnchantList('g', enchantClass.Stat, enchantClass.GodEnchantValue, 0, EnchantStates.Minus);
                }
            }

            if (godEnchantLevel > 0 && GodEnchantStats != null)
            {
                UpdateEnchantList('g', GodEnchantStats[0].Key, GodEnchantStats[0].Value);
                UpdateEnchantList('g', GodEnchantStats[1].Key, GodEnchantStats[1].Value);
                UpdateEnchantList('g', GodEnchantStats[2].Key, GodEnchantStats[2].Value);
                UpdateEnchantList('g', GodEnchantStats[3].Key, GodEnchantStats[3].Value);
            }

            if (godEnchantLevel > 0 && ArmsfusionGodEnchantStats != null)
            {
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[0].Key, ArmsfusionGodEnchantStats[0].Value);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[1].Key, ArmsfusionGodEnchantStats[1].Value);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[2].Key, ArmsfusionGodEnchantStats[2].Value);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[3].Key, ArmsfusionGodEnchantStats[3].Value);
            }
            
            if (godEnchantLevel > 1 && GodEnchantStats != null)
            {
                UpdateEnchantList('g', GodEnchantStats[4].Key, GodEnchantStats[4].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', GodEnchantStats[5].Key, GodEnchantStats[5].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', GodEnchantStats[6].Key, GodEnchantStats[6].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', GodEnchantStats[7].Key, GodEnchantStats[7].Value, 0, EnchantStates.Plus);
            }

            if (godEnchantLevel > 1 && ArmsfusionGodEnchantStats != null)
            {
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[4].Key, ArmsfusionGodEnchantStats[4].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[5].Key, ArmsfusionGodEnchantStats[5].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[6].Key, ArmsfusionGodEnchantStats[6].Value, 0, EnchantStates.Plus);
                UpdateEnchantList('g', ArmsfusionGodEnchantStats[7].Key, ArmsfusionGodEnchantStats[7].Value, 0, EnchantStates.Plus);
            }


            ShowFullStatsTable();
        }

        #endregion

        #region Random Bonus Code

        private void CreateRandomBonusTable()
        {
            if (!Item.Table.Columns.Contains("random_option_set"))
            {
                RandomBonusVisible = Visibility.Collapsed;
            }
            else
            {
                RandomBonusVisible = !string.IsNullOrEmpty(Item["random_option_set"].ToString())
                    ? Visibility.Visible
                    : Visibility.Collapsed;
                if (RandomBonusVisible != Visibility.Visible) return;
            }

            RandomBonusText = Resources.RandomBonus_DefaultText;
            RandomBonusCharacters = Resources.RandomBonus_NotSelected;

            if (RandomBonus == null)
            {
                return;
            }

            RandomBonusText = string.Format(Resources.RandomBonus_Selected, RandomBonus.Chance);

            RandomBonusCharacters = RandomBonusText + ":\n";
            IdianRandomTextConverter converter = new IdianRandomTextConverter();
            foreach (KeyValuePair<string, float> bonus in RandomBonus.RandomBonuses.Where(bonus => !string.IsNullOrEmpty(bonus.Key)))
            {
                RandomBonusCharacters += (string)converter.Convert(bonus, null, "AccentColor", null) + ", ";
            }
            RandomBonusCharacters = RandomBonusCharacters.Remove(RandomBonusCharacters.Length-2, 2);
        }

        private void OpenRandomBonus()
        {
            RandomBonusPage rbPage = new RandomBonusPage();
            RandomBonusViewModel rbViewModel = (RandomBonusViewModel)rbPage.DataContext;

            ModernDialog md = new ModernDialog { Content = rbPage, Title = Resources.RandomBonus_DialogTitle };
            
            rbViewModel.LoadRandomBonusList(Item["random_option_set"].ToString(), randomBonus);
            rbViewModel.Dialog = md;
            md.MaxWidth = 900;
            md.Buttons = new[] { md.OkButton, md.CancelButton };
            md.ShowDialog();

            if (md.GetDialogResult == MessageBoxResult.Cancel) return;

            RandomBonus = rbViewModel.SelectedRandomBonus;

            GetRandomBonusStats();
        }

        private void GetRandomBonusStats()
        {
            if (RandomBonus == null)
            {
                foreach (StatsValuesClass enchantClass in StatsList)
                {
                    if (Math.Abs(enchantClass.RandomBonusValue - 0) > 0)
                    {
                        UpdateEnchantList('r', enchantClass.Stat, enchantClass.RandomBonusValue, 0, EnchantStates.Minus);
                    }

                    enchantClass.RandomBonusValue = 0;
                }
            }
            else
            {
                foreach (KeyValuePair<string, float> bonus in RandomBonus.RandomBonuses)
                {
                    UpdateEnchantList('r', bonus.Key, bonus.Value);
                }
            }
            
            ShowFullStatsTable();
        }

        public void LoadRandomBonus(string id)
        {
            RandomBonus = new RandomBonus(id, Item["random_option_set"].ToString());
            GetRandomBonusStats();
        }

        #endregion

        #region ItemSet

        private void GetItemSet(ItemSets itemSets)
        {
            if (Item == null) return;
            ItemSet statusItemSet = null;

            if (itemSets == null)
            {
                if (ItemSet == null)
                {
                    string[] itemInfo = { Item["name"].ToString(), Item.Table.TableName };
                    statusItemSet = ItemSet.GetItemSet(itemInfo);
                }
            }
            else
            {
                statusItemSet = itemSets.GetItemSet(Item["name"].ToString());
            }
           
            ItemSet = statusItemSet;
            CreateItemSetTable();
        }

        private void CreateItemSetTable()
        {
            if (ItemSet == null)
            {
                ItemSetVisible = Visibility.Collapsed;
                return;
            }

            ItemSetVisible = Visibility.Visible;
            ItemSetText = ItemSet.GetTranslate();

            ItemSetCharacters = ItemSet.GetCharacters(TranslateColor);
        }

        #endregion

        #region Armsfusion

        public void LoadArmsfusionCard(ItemCardViewModel armsfusionCard)
        {
            if (StatsList == null) return;

            foreach (StatsValuesClass stat in StatsList)
            {
                stat.ArmsfusionBonusValue = 0;
                stat.ArmsfusionManaStoneValue = 0;
            }

            if (armsfusionCard == null || armsfusionCard.Item == null)
            {
                ArmsfusionItem = null;
                ArmsfusionBonusCharacters = null;
                ArmsfusionManastones = null;
                return;
            }
            
            ArmsfusionItem = armsfusionCard.Item;
            ArmsfusionBonusCharacters = armsfusionCard.BonusCharacters;
            ArmsfusionBonusVisible = string.IsNullOrEmpty(ArmsfusionBonusCharacters) ? Visibility.Collapsed : Visibility.Visible;
            foreach (StatsValuesClass armsfusionStat in armsfusionCard.StatsList.Where(armsfusionStat => armsfusionStat.BonusValue > 0))
            {
                UpdateEnchantList('a', armsfusionStat.Stat, armsfusionStat.BonusValue, unit: armsfusionStat.Unit);
            }

            ArmsfusionManastoneText = armsfusionCard.ManastoneText;
            armsfusionManastonesMaxLevel = armsfusionCard.ManastonesMaxLevel;
            ArmsfusionManastonesVisible = armsfusionManastonesMaxLevel > 0 ? Visibility.Visible : Visibility.Collapsed;
            
            armsfusionManastones = armsfusionCard.Manastones;
            armsfusionManastones.CollectionChanged += ArmsfusionManastonesChanged;

            foreach (StatsValuesClass armsfusionStat in armsfusionCard.StatsList.Where(armsfusionStat => armsfusionStat.ManaStoneValue > 0))
            {
                UpdateEnchantList('n', armsfusionStat.Stat, armsfusionStat.ManaStoneValue, unit: armsfusionStat.Unit, state: EnchantStates.Plus);
            }

            ArmsfusionTitleColor = armsfusionCard.TranslateColor;
            ArmsfusionGodEnchantStats = armsfusionCard.GodEnchantStats;

            SetArmsfusion();
        }

        private void ArmsfusionManastonesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action != NotifyCollectionChangedAction.Replace) return;

            if (e.NewItems.Cast<ManaStone>().Count(manaStone => manaStone.Row != null) > 0)
            {
                UpdateArmsfusionManastoneStats(ArmsfusionManastones[e.NewStartingIndex], EnchantStates.Plus);
            }

            if (e.OldItems.Cast<ManaStone>().Count(manaStone => manaStone.Row != null) > 0)
            {
                UpdateArmsfusionManastoneStats((ManaStone)e.OldItems[0], EnchantStates.Minus);
                ArmsfusionManastones[e.OldStartingIndex] = new ManaStone(ArmsfusionManastones[e.OldStartingIndex].SlotType,
                    ArmsfusionManastones[e.OldStartingIndex].Index);
            }
        }

        private void SetArmsfusion()
        {
            if (ArmsfusionItem == null)
            {
                ArmsfusionVisible = Visibility.Collapsed;
                return;
            }

            ArmsfusionVisible = Visibility.Visible;
            Byte armsfusionGodEnchantMaxLevel = string.IsNullOrEmpty(ArmsfusionItem["charge_level"].ToString()) ? (byte)0 : Convert.ToByte(ArmsfusionItem["charge_level"]);

            if (armsfusionGodEnchantMaxLevel > 0)
            {
                GodEnchantMaxLevel = string.IsNullOrEmpty(Item["charge_level"].ToString())
                    ? (byte)0
                    : Convert.ToByte(Item["charge_level"]);

                CreateGodEnchantTable();
                if (armsfusionGodEnchantMaxLevel > godEnchantMaxLevel)
                {
                    GodEnchantVisible = Visibility.Visible;
                    GodEnchantMaxLevel = armsfusionGodEnchantMaxLevel;
                }

                AddGodEnchantTableFromArmsfusion();
                ShowFullStatsTable();
            }
        }

        private void OpenArmsfusionManastone(string stoneNumber)
        {
            byte stoneIndex = Convert.ToByte(stoneNumber);

            ManastonePage mp = new ManastonePage();
            ManastonesDialogViewModel mpvm = (ManastonesDialogViewModel)mp.DataContext;

            ModernDialog md = new ModernDialog { Content = mp, Title = Resources.Manastones_DialogTitle };

            mpvm.CurrentManaStone = ArmsfusionManastones[stoneIndex];
            mpvm.MaxLevel = armsfusionManastonesMaxLevel;
            mpvm.Type = ArmsfusionManastones[stoneIndex].SlotType;
            mpvm.Index = ArmsfusionManastones[stoneIndex].Index;
            mpvm.Dialog = md;

            md.MaxWidth = 800;
            md.ShowDialog();

            ArmsfusionManastones[stoneIndex] = mpvm.CurrentManaStone.CloneLite(
                ArmsfusionManastones[stoneIndex].SlotType,
                ArmsfusionManastones[stoneIndex].Index);

            if (ReferenceEquals(md.Tag, "CopyManaStone"))
            {
                CopyArmsfusionManaStoneToAllSlots(mpvm.CurrentManaStone);
            }
            else
            {
                //UpdateArmsfusionManastoneStats(ArmsfusionManastones[stoneIndex], EnchantStates.Plus);
            }
        }

        private void CopyArmsfusionManaStoneToAllSlots(ManaStone sourceManastone)
        {
            for (int i = 0; i < ArmsfusionManastones.Count; i++)
            {
                if (ArmsfusionManastones[i].Visible != Visibility.Visible || ArmsfusionManastones[i].Index == sourceManastone.Index) continue;

                if (((sourceManastone.SlotType != ManaStone.ManaStoneType.Normal
                      && sourceManastone.SlotType != ManaStone.ManaStoneType.Bonus)
                     || (ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Normal
                         && ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Bonus))
                    && (sourceManastone.SlotType != ManaStone.ManaStoneType.Special
                        || ArmsfusionManastones[i].SlotType != ManaStone.ManaStoneType.Special)) continue;

                ArmsfusionManastones[i] = sourceManastone.CloneLite(ArmsfusionManastones[i].SlotType, ArmsfusionManastones[i].Index);

                //UpdateArmsfusionManastoneStats(ArmsfusionManastones[i], EnchantStates.Plus);
            }
        }

        private void UpdateArmsfusionManastoneStats(ManaStone stone, EnchantStates state)
        {
            for (int i = 1; i < 6; i++)
            {
                if (stone.Row == null || string.IsNullOrEmpty(stone.Row["stat_enchant_type" + i].ToString())) continue;
                UpdateEnchantList(
                    'n',
                    stone.Row["stat_enchant_type" + i].ToString().ToLower(),
                    Convert.ToInt32(stone.Row["stat_enchant_value" + i]),
                    0,
                    state);
            }

            ShowFullStatsTable();
        }

        private void DeleteArmsfusionManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (ArmsfusionManastones[index].Row == null) return;

            //UpdateArmsfusionManastoneStats(ArmsfusionManastones[index], EnchantStates.Minus);
            ArmsfusionManastones[index] = new ManaStone(ArmsfusionManastones[index].SlotType, ArmsfusionManastones[index].Index);
        }

        private void CopyArmsfusionManastone(Button button)
        {
            int index = Convert.ToInt32(button.CommandParameter);
            if (ArmsfusionManastones[index].Row == null) return;

            CopyArmsfusionManaStoneToAllSlots(ArmsfusionManastones[index]);
        }

        private void AddGodEnchantTableFromArmsfusion()
        {
            if (ArmsfusionGodEnchantStats == null) return;
            
            CharacterTextConverter converter = new CharacterTextConverter();
            Byte armsfusionGodEnchantMaxLevel = Convert.ToByte(ArmsfusionItem["charge_level"]);
            
            if (!string.IsNullOrEmpty(GodEnchantCharactersLevel1)) GodEnchantCharactersLevel1 += "\n";
            GodEnchantCharactersLevel1 += string.Format(Resources.GodEnchant_CondiEffectAdd, "1") + "\n";

            string caret = "\t  ";
            for (int i = 0; i <= 3; i++)
            {
                GodEnchantCharactersLevel1 += converter.Convert(ArmsfusionGodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
            
            if (armsfusionGodEnchantMaxLevel <= 1) return;

            if (!string.IsNullOrEmpty(GodEnchantCharactersLevel2)) GodEnchantCharactersLevel2 += "\n";
            GodEnchantCharactersLevel2 += string.Format(Resources.GodEnchant_CondiEffectAdd, "2") + "\n";

            caret = "\t";
            for (int i = 4; i <= 7; i++)
            {
                GodEnchantCharactersLevel2 += converter.Convert(ArmsfusionGodEnchantStats.ElementAt(i), null, "+", null) + caret;
                caret = i % 2 == 0 ? "\n" : "\t  ";
            }
        }

        #endregion
    }
}
